package org.kl.bf.service.basic;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.entity.basic.DataRole;
import org.kl.bf.entity.basic.Menu;
import org.kl.bf.entity.basic.Role;
import org.kl.bf.entity.basic.User;
import org.kl.bf.entity.easyui.EasyuiTreeNode;
import org.kl.bf.entity.easyui.EasyuiUtils;
import org.kl.bf.repository.basic.RoleDao;
import org.kl.bf.repository.basic.RoleUserDao;
import org.kl.bf.repository.basic.UserDao;
import org.kl.bf.utils.CRUDUtils;
import org.kl.bf.utils.KLDynamicSpecifications;
import org.kl.bf.utils.KLSearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author Qken
 * @date 2014-3-24
 */
// Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional
public class UserService {

	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private RoleUserDao roleUserDao;
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	

	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public User getUser(String guid) {
		// return userDao.find(User.class,guid);
		return userDao.findOne(guid);
	}

	/**
	 * 查找用户信息（包括角色，菜单）
	 * 
	 * @param id
	 * @return
	 */
	public User findUserWithAllInfo(String id) {
		return null;
	}

	/**
	 * 查找用户信息（包括角色，菜单）
	 * 
	 * @param id
	 * @return
	 */
	public User findUserByEmployeeId(String id) {
		return userDao.findByEmployeeId(id).get(0);
	}

	/**
	 * 查找用户信息（包括角色）
	 * 
	 * @param id
	 * @return
	 */
	public User findUserWithRole(User user) {

		return null;
	}

	public void saveUser(User entity) {
		userDao.save(entity);
	}

	public void deleteUser(String guid) {
		userDao.delete(guid);
	}

	public List<User> getAllUser() {
		return (List<User>) userDao.findAll();
	}

	public User getByLoginNo(String loginNo) {
		return userDao.findByLoginNo(loginNo);
	}

	/**
	 * 获取角色下的所有用户
	 */
	public List<User> getUsersByRole(String roleId) {
		return roleUserDao.getUsersByRoleId(roleId);
	}
	
	/**
	 * 获取角色下的所有用户并按部门过滤
	 */
	public List<User> getUsersByRoleAndOrg(String roleId, String orgIds,ServletRequest request) {
		return roleUserDao.getUsersByRoleIdAndOrgIds(roleId, orgIds, 0, 0,request);
	}

	/**
	 * 获取角色下的所有用户并按部门过滤(分页)
	 */
	public List<User> getUsersByRoleAndOrg(String roleId, String orgIds, int pageNumber, int pageSize,ServletRequest request) {
		return roleUserDao.getUsersByRoleIdAndOrgIds(roleId, orgIds, pageNumber, pageSize,request);
	}
	
	/**
	 * 获取角色下的所有用户的总数并按部门过滤
	 */
	public int getUsersByRoleIdAndOrgIdsCount(String roleId, String orgIds, ServletRequest request) {
		return roleUserDao.getUsersByRoleIdAndOrgIdsCount(roleId, orgIds,request);
	}

	/**
	 * 获取某个角色的所有用户Id
	 */
	public List<String> getUsersIdByRoleNo(String roleNo) {
		Role role = roleDao.findByRoleNo(roleNo);
		return roleUserDao.getUserIds(role.getId());
	}

	/**
	 * 按邮箱查找用户
	 */
	public User findUserByEmail(String email) {
		return userDao.findByEmail(email);
	}
	
	/**
	 * 按条件查找全部
	 */
	public List<User> searchAll(Map<String, Object> searchParams) {
		return userDao.searchAll(searchParams, User.class);
	}

	public Page<User> getUser(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType) {
		PageRequest pageRequest = CRUDUtils.buildPageRequest(pageNumber, pageSize, sortType, "desc");
		Specification<User> spec = buildSpecification(searchParams);
		return userDao.findAll(spec, pageRequest);
	}

	public Page<User> getUser(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType, String orderType) {
		PageRequest pageRequest = CRUDUtils.buildPageRequest(pageNumber, pageSize, sortType, orderType);
		Specification<User> spec = buildSpecification(searchParams);
		return userDao.findAll(spec, pageRequest);
	}

	public void addUserRoles(String userId, String dataRoleIds, String roleIds) {
		User u = userDao.findOne(userId);
		if (u != null) {
			String[] drIds = dataRoleIds.split(",");
			String[] rIds = roleIds.split(",");
			u.setDataRoleSet(new HashSet<DataRole>());
			u.setRoleSet(new HashSet<Role>());
			for (String drId : drIds) {
				if (StringUtils.isNotBlank(drId)) {
					DataRole dr = new DataRole();
					dr.setId(drId.trim());
					u.getDataRoleSet().add(dr);
				}
			}
			for (String rId : rIds) {
				if (StringUtils.isNotBlank(rId)) {
					Role r = new Role();
					r.setId(rId.trim());
					u.getRoleSet().add(r);
				}
			}
		}
		userDao.save(u);
	}

	/**
	 * 给角色分配用户，SQL实现
	 * 
	 * @param userIds
	 * @param roleId
	 */
	public void addRoleUsersWithSQL(String userIds, String roleId) {
		String[] uIds = StringUtils.split(userIds, ",");
		for (String uId : uIds) {
			roleUserDao.addRoleUser(roleId, uId);
		}
	}

	/**
	 * 给角色删除用户，SQL实现
	 * 
	 * @param userIds
	 * @param roleId
	 */
	public void deleteRoleUsersWithSQL(String userIds, String roleId) {
		String[] uIds = StringUtils.split(userIds, ",");
		for (String uId : uIds) {
			roleUserDao.deleteUserForRole(roleId, uId);
		}
	}

	public void addRoleUsers(String userIds, String dataRoleId, String roleId) {
		String[] uIds = userIds.split(",");
		List<User> userList = new ArrayList<User>();
		for (int i = 0; i < uIds.length; i++) {
			if (StringUtils.isNotBlank(uIds[i])) {
				User u = userDao.findOne(uIds[i]);
				userList.add(u);
			}
		}
		List<User> userOtherList = userDao.findAll();
		userOtherList.removeAll(userList);
		if (StringUtils.isNotBlank(roleId)) {
			Role r = new Role();
			// r.setId(roleId.trim());
			r = roleDao.findOne(roleId);
			for (int i = userList.size() - 1; i >= 0; i--) {
				User u1 = userList.get(i);
				if (u1.getRoleSet().contains(r)) {
					userList.remove(u1);
				} else {
					u1.getRoleSet().add(r);
				}
			}
			for (int i = userOtherList.size() - 1; i >= 0; i--) {
				User u2 = userOtherList.get(i);
				if (u2.getRoleSet().contains(r)) {
					u2.getRoleSet().remove(r);
					userList.add(u2);
				}
			}
		}
		if (StringUtils.isNotBlank(dataRoleId)) {
			DataRole dr = new DataRole();
			dr.setId(dataRoleId.trim());
			for (int i = userList.size() - 1; i >= 0; i--) {
				User u1 = userList.get(i);
				if (u1.getDataRoleSet().contains(dr)) {
					userList.remove(u1);
				} else {
					u1.getDataRoleSet().add(dr);
				}
			}
			for (int i = userOtherList.size() - 1; i >= 0; i--) {
				User u2 = userOtherList.get(i);
				if (u2.getDataRoleSet().contains(dr)) {
					u2.getDataRoleSet().remove(dr);
					userList.add(u2);
				}
			}
		}
		// userDao.save(userList);
	}

	public String multiDelete(String ids) {
		String[] idArray = StringUtils.split(ids, ",");
		int i = 0;
		for (String id : idArray) {
			if (StringUtils.isNotBlank(id)) {
				userDao.delete(id);
				i++;
			}
		}
		return "删除" + i + "条记录";
	}

	@Deprecated
	public User getUserByStaffInfoId(String id) {
		// return userDao.findByStaffinfoId(id);
		return null;
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<User> buildSpecification(Map<String, Object> searchParams) {
		Map<String, KLSearchFilter> filters = KLSearchFilter.parse(searchParams);
		Specification<User> spec = KLDynamicSpecifications.byKLSearchFilter(filters.values(), User.class);
		return spec;
	}

	/**
	 * 获取用户的菜单
	 * 
	 * @return
	 */
	public List<EasyuiTreeNode> getUserMenus(String userId, String rootId) {
		Set<Menu> userMenus = new HashSet<Menu>();
		User user = userDao.findOne(userId);
		Set<Role> roles = user.getRoleSet();
		for (Role role : roles) {
			Set<Menu> roleMenus = role.getRoleMenus();
			for (Menu menu : roleMenus) {
				if (menu.getRootId().equals(rootId)) {
					userMenus.add(menu);
				}
			}
		}
		List<EasyuiTreeNode> easyuiTree = new ArrayList<EasyuiTreeNode>();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String contextPath = request.getContextPath();
		// mark 此处同步一下收藏夹 Qken
		for (Menu menu : userMenus) {
			easyuiTree.add(EasyuiUtils.buildMenuTree(menu, contextPath));
		}
		Collections.sort(easyuiTree, new Comparator<EasyuiTreeNode>() {
			public int compare(EasyuiTreeNode arg0, EasyuiTreeNode arg1) {
				if (arg0.getDisplayOrder() != null && arg1.getDisplayOrder() != null) {
					return arg0.getDisplayOrder().compareTo(arg1.getDisplayOrder());
				} else {
					return 0;
				}

			}
		});
		return easyuiTree;
	}

	/**
	 * 获取用户的菜单根节点
	 * 
	 * @return
	 */
	public List<Menu> getUserMenusRoot(String userId) {
		List<Menu> userMenuRoot = new ArrayList<Menu>();
		User user = userDao.findOne(userId);
		Set<Role> roles = user.getRoleSet();
		for (Role role : roles) {
			Set<Menu> roleMenus = role.getRoleMenus();
			for (Menu menu : roleMenus) {
				if (StringUtils.isEmpty(menu.getMenuParentId()))
					if (!userMenuRoot.contains(menu)) {
						userMenuRoot.add(menu);
					}
			}

		}

		Collections.sort(userMenuRoot, new Comparator<Menu>() {
			public int compare(Menu arg0, Menu arg1) {
				if (arg0.getDisplayOrder() != null && arg1.getDisplayOrder() != null) {
					return arg0.getDisplayOrder().compareTo(arg1.getDisplayOrder());
				} else {
					return 0;
				}

			}
		});
		return userMenuRoot;
	}

	/**
	 * 获取用户的收藏夹
	 * 
	 * @return
	 */
	public List<EasyuiTreeNode> getFavMenus(String userId) {
		User user = userDao.findOne(userId);
		Set<Menu> favMenus = user.getFavMenus();
		List<EasyuiTreeNode> easyuiTree = new ArrayList<EasyuiTreeNode>();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String contextPath = request.getContextPath();
		// mark 此处同步一下收藏夹 Qken
		for (Menu menu : favMenus) {
			easyuiTree.add(EasyuiUtils.buildMenuTree(menu, contextPath));
		}
		return easyuiTree;
	}

	/**
	 * 新增用户收藏夹
	 * 
	 * @return
	 */
	public void addFavMenus(String userId, String favMenuId) {
		User user = userDao.findOne(userId);
		Set<Menu> favMenus = user.getFavMenus();
		Menu menu = new Menu();
		menu.setId(favMenuId);
		if (!favMenus.contains(menu)) {
			favMenus.add(menu);
			user.setFavMenus(favMenus);
			userDao.save(user);
		}
	}

	/**
	 * 删除用户收藏夹
	 * 
	 * @return
	 */
	public void removeFavMenus(String userId, String favMenuId) {
		User user = userDao.findOne(userId);
		Set<Menu> favMenus = user.getFavMenus();
		for (Menu menu : favMenus) {
			if (menu.getId().equalsIgnoreCase(favMenuId))
				favMenus.remove(menu);
		}
		user.setFavMenus(favMenus);
		userDao.save(user);
	}

	public List<User> getAllUser(Map<String, Object> searchParams, String sortType, String orderType) {
		Specification<User> spec = KLDynamicSpecifications.buildSpecification(searchParams, User.class);
		return userDao.findAll(spec, CRUDUtils.buildSort(sortType, orderType));
		
	}
	
    /**
     * 根据角色Id 查询用户
     * @param roleId
     * @return
     */
	public List<User> findUserListByRoleId(String roleId) {
		final List<User> result=new ArrayList<User>();
		StringBuilder sql = new StringBuilder("select us.login_no loginNo ,us.true_name trueName from   basic_user us ,basic_user_role ur where ur.role_id='"+roleId+"' and  us.id=ur.user_id");
		this.jdbcTemplate.query(sql.toString(),new RowCallbackHandler() {
			
			@Override
			public void processRow(ResultSet rs) throws SQLException {
				 User user=new User();
				 user.setLoginNo(rs.getString("loginNo"));
				 user.setTrueName(rs.getString("trueName"));
				result.add(user);
			}
		});
	
		return result;
    }
}
